/*
 * matrixkeyboard.h
 *
 *  Created on: Dec 8, 2021
 *      Author: t1019
 */

#ifndef MATRIXKEYBOARD_H_
#define MATRIXKEYBOARD_H_

#include "stdint.h"
#include "stm32l0xx_hal.h"

namespace bt_matrixkeyboard {

typedef enum
{
	MKEY_NORMAL = 0u,		/*<未动作*/
	MKEY_DET_PRESSED = 1u,	/*<检测按下中*/
	MKEY_PRESSING = 2u,		/*<已按下*/
	MKEY_PRESSING_CD = 3u,	/*<重复按下超时中*/
	MKEY_DET_RELEASED = 4u	/*<检测抬起中*/
}e_KeyStatus;

typedef struct
{
	GPIO_TypeDef* gpio;
	uint32_t pin;
}s_MatrixKeyboardLine;

typedef struct
{
	uint16_t timeout;
	e_KeyStatus status;
}s_MatrixKeyStatus;

class MatrixKeyboard {
public:
	MatrixKeyboard(const uint8_t out_num, const uint8_t in_num);
	void setLines(const s_MatrixKeyboardLine* output, const s_MatrixKeyboardLine* input);
	void setAllowMultitriggering(bool trig);
	void setValue(const char * val);
	void handler(uint16_t period);
	char getEvent();
	virtual ~MatrixKeyboard();
private:
	inline void _port_gpioset(s_MatrixKeyboardLine p,bool val)
	{
		HAL_GPIO_WritePin(p.gpio,p.pin,val?GPIO_PIN_SET:GPIO_PIN_RESET);
	}
	inline bool _port_gpioget(s_MatrixKeyboardLine p)
	{
		return HAL_GPIO_ReadPin(p.gpio,p.pin);
	}
	void _keystatus_refresh(uint8_t o, uint8_t i, bool val, uint16_t period);
	void _append_event(char e);
	bool allow_multitriggering;					//是否允许重复触发
	s_MatrixKeyStatus *matrix;					//矩阵状态
	uint8_t outputlines_num, inputlines_num;	//控制线和检测线个数
	const s_MatrixKeyboardLine *outputlines, *inputlines;
	const char* martixvalue;					//矩阵按键值,横坐标out 纵坐标in

	const uint16_t change_timeout = 20;			//状态切换消抖超时
	const uint16_t trig_timeout = 500;			//重复触发超时
	const uint8_t queue_num = 10;
	char* queue;
	uint8_t scan_idx;
};

} /* namespace bt_matrixkeyboard */

#endif /* MATRIXKEYBOARD_H_ */
